#pragma once

#include "stdafx.h"
#include "time.h"
#include "MultiScalePyramid.h"
#include "Texton.h"
#include "TextonGroup.h"
#include "cvgabor.h"
#include "windows.h"
#include "Commdlg.h"
#include "TexSynthProps.h"

#define POW2(x) (x)*(x)

#define NUM_TEXTON_DETECTORS 11
#define DETECTOR_PATH "..\\Detectors\\Set1"
#define TEXTON_PATH "Textons"
#define OUTPUT_FOLDER "Output\\"
//#define DETECTOR_PATH "..\\Detectors\\Set1"
//#define TEXTON_PATH "..\\Textons"
//#define OUTPUT_FOLDER "..\\Output\\"
#define PYRAMID_SCALE 0.7
#define NUM_LEVELS 5
#define FIRST_LEVEL 0 /*(NUM_LEVELS-2)*/
#define MAX_NUM_OF_CLUSTERS 12

#define TWO_PI 6.283185307
#define MY_PI 3.141592653
#define LOG2 0.30102999566398119521373889472449

#include <vector>
#include <set>
#include <algorithm>
using namespace std;


namespace TextureSynthesizer {
	int CalculateDifferenceGray(IplImage* detectorImage, IplImage* inputImage, int xOffset, int yOffset);	
	int CalculateDifferenceRGB(IplImage* detectorImage, IplImage* inputImage, int xOffset, int yOffset);	
	void LoadTextonDetectors(IplImage** detectors, int startIdx, char* strFolderPath, int numDetectors);	
	IplImage** ExtractDetectorsFromImage(IplImage* image, int detectorWidth, int detectorHeight);	
	vector<vector<Texton*> > ClusterTextons(vector<Texton*> vecTextons);	
	vector<TextonGroup> GroupOverlappingTextons(const vector<Texton*>& _vecTextons, IplImage* orig);	
	int CalculateMedian(IplImage* image, IplImage* detector);	
	void MakeGaborFilters(IplImage** gabors, int& count);	
	CvMat* CreateHistograms(vector<Texton* >& hits, IplImage* RGBimage, bool use_intensity);	
	void GroupTextonsUsingHistograms(vector<Texton* >& hits, 
								 IplImage* RGBimage, 
								 vector<TextonGroup*>& groups,
								 int surroundingHistPad,
								 int* num_clusters,
								 bool use_intensity);
	void ExtractTextons(System::Object^ filenameStr);
	void CreateNewTexture(System::Object^ o);
	CvRect GetMaskBoundingRect(IplImage* img);
	void CreateUniformTexture(System::Object^ s);
	void ExtractTextonsUsingGrid(System::Object^ filenameString);
	bool CanCover(IplImage* target, TextonGroup* texton, int x, int y);
	void PutTexton(IplImage* output, IplImage* outputAlpha, TextonGroup* g, int x, int y);
	bool IsBlank(IplImage* targetImage, CvRect rect, int targetScore);
	void ShowImage(IplImage* image);
	CvMat* CalcHistogramForRect(IplImage* img, CvRect r, int bins, IplImage* histMask);
	bool IsPointBlack(IplImage* i,int x,int y);
	bool CanBaloonGrow(IplImage* i, CvPoint pt, int a, int b, int w, int h);
	bool CanBaloonMoveBy(IplImage* i,CvPoint& pt, int by, int a, int b, System::Drawing::Size s);
	bool CanBaloonGrowBy(IplImage* i,CvPoint pt, int by, int& a, int& b, System::Drawing::Size s);
	void InflateBaloonFromPoint(CvPoint& pt, IplImage* mask, int& a, int& b, System::Drawing::Size s, TexSynthProps^ props);
	bool CanBaloonGrowBySize(IplImage* mask, CvPoint pt, int& a, int& b, System::Drawing::Size s);
}